Skip to content

Updates to use bearer auth#260

Draft
Nexarian wants to merge 3 commits into
jasonacox:mainfrom
Nexarian:feature/bearer-token-auth
Draft

Updates to use bearer auth#260
Nexarian wants to merge 3 commits into
jasonacox:mainfrom
Nexarian:feature/bearer-token-auth

Conversation

@Nexarian
Copy link
Copy Markdown
Contributor

No description provided.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 18, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 5.76923% with 686 lines in your changes missing coverage. Please review.
✅ Project coverage is 26.25%. Comparing base (a07cf63) to head (329d80d).

Files with missing lines Patch % Lines
pypowerwall/tedapi/__init__.py 7.66% 457 Missing and 1 partial ⚠️
pypowerwall/tedapi/tedapi_pb2.py 1.38% 213 Missing and 1 partial ⚠️
pypowerwall/tedapi/pypowerwall_tedapi.py 0.00% 12 Missing ⚠️
pypowerwall/tedapi/__main__.py 0.00% 2 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #260      +/-   ##
==========================================
- Coverage   28.25%   26.25%   -2.00%     
==========================================
  Files          35       35              
  Lines        5596     6163     +567     
  Branches      778      863      +85     
==========================================
+ Hits         1581     1618      +37     
- Misses       3938     4467     +529     
- Partials       77       78       +1     
Flag Coverage Δ
py3.10 26.25% <5.76%> (-2.00%) ⬇️
py3.11 26.25% <5.76%> (-2.00%) ⬇️
py3.12 26.25% <5.76%> (-2.00%) ⬇️
py3.13 26.25% <5.76%> (-2.00%) ⬇️
py3.9 26.27% <5.76%> (-2.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Nexarian
Copy link
Copy Markdown
Contributor Author

Nexarian commented Feb 18, 2026

@jasonacox This is a draft of two changes:

  • To use the bearer token approach that allows at least some people to use hardwired again
  • To update the queries fresh from Tesla's APK.

Arguably these could be split out, but my general approach is:

  • Submit a draft
  • Discuss
  • Then submit the real thing!

@jasonacox jasonacox added the enhancement New feature or request label Mar 3, 2026
@jasonacox-sam
Copy link
Copy Markdown
Collaborator

jasonacox-sam commented May 23, 2026

Thanks for pointing me here, @Nexarian. I've now read through all three commits in detail. Here's my review:

What's Good

The proto schema work is solid — going from 234 to 792 lines with proper APK-verified enums, field numbers, and message types is exactly the ground-truth correction we need. The AuthEnvelope/SignedGraphQLQuery design is clean, and the staging approach makes sense.

Update after APK analysis (see #305 comment): I ran targeted string searches on the Tesla One APK index.android.bundle and confirmed the core infrastructure — AuthEnvelope, externalAuth.type, PRESENCE, bearer token flow (login/Basicaccess_token), ECDSA signing, MessageEnvelope, DELIVERY_CHANNEL/LOCAL_PARTICIPANT enums, and heavy proto.CarServer usage (846 references). The one gap: SignedGraphQLQuery as a specific protobuf message name has 0 direct hits, but SignedMessage + GraphQLQuery + ECDSA all exist separately — likely a descriptive naming choice or minified away in Hermes bytecode.

Suggestions for Staging

As I outlined on #305, I think this should land in stages rather than one big merge:

  1. Proto schema + pb2 regeneration — This is the foundation. Can land independently with zero auth changes. Just swap tedapi.proto, regenerate tedapi_pb2.py, add .pyi type stubs, and update existing message construction to use the new enums.

  2. GraphQL query modernization — Replace inline payload.send.text queries with _build_signed_query() + signature constants. Still using basic auth, just modernized query format.

  3. Bearer token auth — Add auth_mode parameter, _send_cmd()/_parse_response() abstraction, login/logout lifecycle. This is the behavioral change.

Splitting it this way lets us test each layer independently and gives users a safe upgrade path.

Specific Code Notes

  • _bearer_login() — The POST to /api/login/Basic is straightforward, but we should handle token expiry and automatic re-auth. A 401 from the gateway mid-session shouldn't require user intervention.

  • ECDSA-P521 signing constants — These are hardcoded in __init__.py. If Tesla rotates certificates (they have before), we'll need to update them. Worth documenting where these come from (APK version, specific class) so future maintainers know where to look.

  • tedapi.proto — The new enums (DELIVERY_CHANNEL_LOCAL_HTTPS, LOCAL_PARTICIPANT_INSTALLER, etc.) are a big improvement over magic numbers. But we should verify the field numbers haven't shifted against the current basic-auth path before merging — a wrong field number would silently break existing users.


After posting on #305 and thinking through this more carefully, I want to add some harder feedback here too — because this PR is where the code lives.

The Powerwall Testing Gap 🔴

You can't test any of this on a Powerwall — you don't have one. That's not a criticism, it's a constraint that has to shape how we merge this work. pypowerwall's core audience is Powerwall users (TEG, PW2, PW3, PW+), and changes to the auth path and query layer affect all of them.

Before any of these stages land in main, we need at least one community member with an actual Powerwall to validate that:

  • Existing basic auth behavior is unchanged
  • The new query formats return identical data on Powerwall hardware
  • Bearer auth (when opt-in) works or fails gracefully on a TEG

Please add a "looking for Powerwall testers" callout to the PR description. That's not optional — it's the gate.

Coverage: 5.76% on 686 Changed Lines ❌

That's not mergeable for a change this deep in the auth and query stack. The critical paths need tests — at minimum the bearer login flow, the signed query construction, and the AuthEnvelope wrapping. I know writing tests for TEDAPI is harder than most things in this codebase, but this is the tradeoff for touching foundational code.

New Endpoints Need Hardware Gating ⚠️

get_ieee20305(), get_eaton_sbii(), get_pinv_self_test(), get_protection_trip_test() — I was too quick to call these "valuable additions" in my earlier comment. They're smart inverter / Eaton SBII interfaces. What do they return on a Powerwall? Do they error, return empty, or behave unpredictably?

These need to be gated by hardware type or scoped to an inverter-specific module before they go into core. They shouldn't be callable (or silently fail) in a Powerwall context.

AuthEnvelope Scope — Still Need an Answer

Is AuthEnvelope wrapping required only in bearer mode, or is it now required for all new query types regardless of auth method? The answer determines whether this is a bearer-mode addition or a breaking structural change for all TEDAPI callers. Please clarify in the PR description.


Happy to work through the staged PRs once those gates are clear. The bearer auth path is genuinely important and worth doing right.

See also my APK analysis on #305 — I confirmed the core infrastructure (AuthEnvelope, bearer auth, ECDSA, proto schema) is present in the Tesla One APK. The analysis doesn't change the pushback above (split PRs, Powerwall testing, coverage), but it does mean the underlying claims are ground-truth verified rather than speculative. That shifts the conversation from "is this real?" to "how do we merge it safely?"

— Sam ⚡

@Nexarian
Copy link
Copy Markdown
Contributor Author

@jasonacox-sam

Is AuthEnvelope wrapping required only in bearer mode, or is it now required for all new query types regardless of auth method? The answer determines whether this is a bearer-mode addition or a breaking structural change for all TEDAPI callers. Please clarify in the PR description.

I don't know. Can you examine the Tesla One APK and see what it uses?

@jasonacox-sam
Copy link
Copy Markdown
Collaborator

Good question, @Nexarian — and I should have been more precise about what I can and can't determine here.

From the code in this PR: AuthEnvelope wrapping is bearer-mode-only by design. Your _send_cmd() has an explicit branch:

if self.auth_mode == "bearer":
    auth_env = tedapi_pb2.AuthEnvelope()
    auth_env.payload = pb.message.SerializeToString()
    auth_env.externalAuth.type = 1  # PRESENCE
    data = auth_env.SerializeToString()
else:
    data = pb.SerializeToString()  # raw Message, no wrapping

Same pattern in _parse_response() — AuthEnvelope unwrapping only happens in bearer mode.

From the APK: I can only see one auth path — bearer. The Tesla One app is a mobile client that authenticates via login/Basicaccess_token and uses AuthEnvelope with EXTERNAL_AUTH_TYPE_PRESENCE universally. The APK doesn't show a basic auth path at all, so it can't tell us whether the gateway requires AuthEnvelope for basic auth connections using the new signed query format.

The honest answer: I can't determine from the APK alone whether the new SignedGraphQLQuery + ECDSA query format works without AuthEnvelope wrapping over basic auth. The APK only exercises the bearer path. Your PR assumes it does (by keeping basic auth raw and only wrapping in bearer mode) — but only hardware testing can confirm that assumption.

What we do know:

  • Basic auth with the old inline text queries works fine (years of production use)
  • Bearer auth with AuthEnvelope + signed queries works (your testing on your inverter)
  • The gap: basic auth + new signed query format, no AuthEnvelope — untested

I don't have access to a Powerwall or inverter to test this. If you can try sending a signed query via basic auth (without AuthEnvelope) to your hardware, that would close the gap. If it fails, then AuthEnvelope is universal for the new query format and the PR needs to wrap in both modes.

— Sam ⚡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants